The Chicago Board of Ethics requires that all lobbyists engaging with City officials register with the Board and file regular activity reports. The activity reports are filed electronically and include compensation paid to lobbyists by clients (the organizations and firms that hire lobbyists), lobbyist contributions to public and elected City officials, and lobbying activities (meetings with government departments or officials) conducted on behalf of clients.
The recent controversy surrounding unregistered lobbying by individuals contacting Mayor Rahm Emmanuel through his personal email account (see here, here, and here), suggests that there is additional unregistered lobbying activity happening in Chicago. This analysis necessarily focuses only on registered activity reported to the City and made electronically available on the City of Chicago’s Open Data Portal.
# aggregate by year to show trend
# what happened in 2017? why seasonality?
# fourier transformation - time to frequency domain
# axes labels, label quarter only, year underneath
# move legend onto plot
# Summarise data into necessary format
#act_summ <-
activity %>%
#filter(!str_detect(CLIENT_INDUSTRY, 'REAL ESTATE')) %>%
mutate(year = format(PERIOD_START, '%Y'),
PERIOD_START = as.yearqtr(PERIOD_START, format = "%Y-%m-%d")) %>%
group_by(year, ACTION) %>%
summarise(n = n()) %>%
ggplot(aes(year, n)) +
geom_line(aes(group=ACTION, color=ACTION), size = 1) +
scale_color_manual(values = as.vector(dark_colors[c('blue', 'purple', 'red')])) +
scale_y_continuous(label=comma) +
labs(title="Lobbying activity appears to have shifted toward Administrative \nactions since 2016",
subtitle="Annual Lobbying Actions by Type, 2012 - 2018",
caption="Source: City of Chicago Lobbyist Data, Activity",
x = "Years",
y = "Number of Lobbying Actions") +
theme_claire +
theme(legend.position = c(0.15, 0.8))
Lobbying is a commonplace activity at all levels of government. In Chicago, lobbying “Actions” are divided into three categories: Administrative, Legislative, and Both. Administrative actions are meant to spur administrative action, including meetings regarding contract implementation, marketing services to City agencies, or submitting information regarding redevelopment plans. Legislative actions are intended to encourage support or opposition for specific ordinances or bills before the City legislature. The “Both” category includes some combination of the two. There is a notable increase in the number of Administrative actions beginning in 2016 and continuing to the present. this trend warrants further exploration.
b <- activity %>%
filter(PERIOD_START > as.Date('2014-12-31')) %>%
mutate(ACTION_SOUGHT_WORDS = as.vector(str_split(ACTION_SOUGHT, pattern = c(" ", ", ")))) %>%
#group_by(ACTION) %>%
summarise(WORDS = paste(ACTION_SOUGHT, collapse = ", ")) %>%
mutate(WORDS_SEP = as.vector(str_split(WORDS, pattern = "[^a-zA-Z0-9]? ")))
common_words <- c("A", "AND", "AT", "OF", "IN", "THE", "BE", "TO", "THAT", "HAVE",
"IT", "/", "&", "FOR", "N", "E", "W", "S", "L", "WITH", "ON")
# Probably a better way to do this
#admin <- data.frame(table(b$WORDS_SEP[1])) %>%
# mutate(ACTION = 'ADMINISTRATIVE') %>%
# rename(WORD = Var1, COUNT = Freq) %>%
# arrange(desc(COUNT)) %>%
# slice(1:30)
#both <- data.frame(table(b$WORDS_SEP[2])) %>%
# mutate(ACTION = 'BOTH') %>%
# rename(WORD = Var1, COUNT = Freq) %>%
# arrange(desc(COUNT)) %>%
# slice(1:30)
#legis <- data.frame(table(b$WORDS_SEP[3])) %>%
# mutate(ACTION = 'LEGISLATIVE') %>%
# rename(WORD = Var1, COUNT = Freq) %>%
# arrange(desc(COUNT)) %>%
# slice(1:30)
#word_counts <- admin %>%
# rbind(both) %>%
# rbind(legis) %>%
# filter(!(WORD %in% common_words))
word_counts <- data.frame(table(b$WORDS_SEP[1])) %>%
rename(WORD = Var1, COUNT = Freq) %>%
filter(!(WORD %in% common_words)) %>%
arrange(desc(COUNT)) %>%
slice(1:50)
word_counts %>%
ggplot(aes(size = COUNT, label = WORD, color = COUNT)) +
geom_text_wordcloud() +
scale_size(range = c(2, 8), guide = FALSE) +
scale_color_continuous(low = light_colors['blue'], high = dark_colors['blue']) +
scale_y_continuous(breaks = NULL) +
scale_x_continuous(breaks = NULL) +
labs(x = '', y = '') +
#facet_grid(rows = vars(ACTION), switch="both") +
labs(title="Real estate developments are the most frequently discussed items \nin lobbying meetings",
subtitle="Most Freqently Used Words in Activity Descriptions, 2015-2018",
caption="Source: City of Chicago Lobbyist Data, Activity") +
theme_claire +
theme(panel.background = element_blank(),
panel.border = element_rect(color="black",size=1, fill=NA),
strip.background = element_rect(color="black",size=0.5),
legend.position = "none")
activity %>% filter(str_detect(ACTION_SOUGHT, "RIDE")) %>% arrange(desc(PERIOD_START))
## # A tibble: 443 x 15
## LOBBYING_ACTIVI… PERIOD_START PERIOD_END ACTION ACTION_SOUGHT DEPARTMENT
## <dbl> <date> <date> <chr> <chr> <chr>
## 1 170922 2018-07-01 2018-09-30 BOTH RIDESHARE OP… BUSINESS …
## 2 170927 2018-07-01 2018-09-30 BOTH RIDESHARE OP… MAYORS OF…
## 3 170923 2018-07-01 2018-09-30 BOTH RIDESHARE LE… CITY COUN…
## 4 170924 2018-07-01 2018-09-30 ADMIN… RIDESHARE OP… LAW DEPAR…
## 5 170925 2018-07-01 2018-09-30 BOTH RIDESHARE OP… LEGISLATI…
## 6 170926 2018-07-01 2018-09-30 ADMIN… RIDESHARE OP… TRANSPORT…
## 7 170921 2018-07-01 2018-09-30 ADMIN… RIDESHARE OP… AVIATION
## 8 172315 2018-07-01 2018-09-30 LEGIS… RIDE SHARE O… CITY COUN…
## 9 172352 2018-07-01 2018-09-30 LEGIS… RIDE SHARE O… CITY COUN…
## 10 173062 2018-07-01 2018-09-30 LEGIS… RIDE SHARE O… CITY COUN…
## # … with 433 more rows, and 9 more variables: CLIENT_ID <dbl>,
## # CLIENT_NAME <chr>, LOBBYIST_ID <dbl>, LOBBYIST_FIRST_NAME <chr>,
## # LOBBYIST_MIDDLE_INITIAL <chr>, LOBBYIST_LAST_NAME <chr>,
## # CREATED_DATE <chr>, CLIENT_INDUSTRY <chr>, LOBBYIST_NAME <chr>
Regardless of the type of activity (Administrative, Legislative, or Both), the most commonly used in the activity description are words like “zoning”, “development”, and “approval”. This suggests the the majority of the lobbying meetings of all types center on issues surrounding real estate development.
# Top 25 flag
top_20 <- compensation %>%
group_by(CLIENT_NAME) %>%
summarise(sum = sum(COMPENSATION_AMOUNT), cnt = n()) %>%
arrange(desc(sum)) %>%
slice(1:20) %>%
select(CLIENT_NAME)
compensation %<>% mutate(TOP20 = ifelse(CLIENT_NAME %in% top_20$CLIENT_NAME, "Yes", "No"))
c <- compensation %>%
mutate(PERIOD_START = as.yearqtr(PERIOD_START, format = "%Y-%m-%d")) %>%
#filter(PERIOD_START < as.Date('2018-07-01')) %>%
group_by(TOP20, PERIOD_START) %>%
summarise(sum = sum(COMPENSATION_AMOUNT), n = n()) %>%
mutate(sum = sum/1000000) %>%
ggplot(aes(PERIOD_START, sum)) +
geom_col(aes(fill=factor(TOP20, levels=c("No","Yes")))) +
scale_y_continuous(label=dollar_format()) +
scale_x_yearqtr(limits = c('2012 Q1', '2018 Q4'), format = "%YQ%q", n = 28) +
scale_fill_manual(values=c(as.vector(light_colors['blue']), as.vector(dark_colors['blue']))) +
labs(title="The Top 20 Clients Pay ~25% of Lobbyist Compensation",
subtitle="Total Quarterly Lobbyist Compensation, 2012 - 2018",
caption="Source: City of Chicago Lobbyist Data, Compensation",
x = "Time",
y = "Total Lobbyist Compensation (in Millions)") +
theme_claire +
theme(axis.text.x = element_text(angle = 90, hjust = 1),
legend.box = 'horizontal',
legend.position = c(0.46, 0.85)) +
guides(fill=guide_legend(title="Top 20"))
c + geom_point(data = compensation %>%
mutate(PERIOD_START = as.yearqtr(PERIOD_START, format = "%Y-%m-%d")) %>%
#filter(PERIOD_START < as.Date('2018-07-01')) %>%
group_by(PERIOD_START) %>%
summarise(pct_25 = sum(COMPENSATION_AMOUNT) * .25/1000000, n = n()), aes(PERIOD_START, pct_25, color = dark_colors['red'])) +
scale_color_identity(name = "25% Mark",
labels = c(""),
guide = "legend")
Clients pay lobbyists to represent their interests to Chicago government officials. On a quarterly basis, that total amount paid by clients to lobbyists routinely tops $15 Million, indicating the size of the lobbying industry in Chicago. Further, 20 clients out of over 3,000 found in the data routinely constitute about 25% of that total. There is clear seasonality in the total payment amounts that also matches seasonal trends in lobbying activity and lobbyist contributions. It is unclear exactly why this is, but it may be related to the City of Chicago’s budgeting process. A balanced budget must be passed by City Council by December 31 of each year, so individual departments are likely to be making decisions around funding allocations during the first few months of the year.
# Map actual name to target name
keys <- c("ACADEMY FOR URBAN SCHOOL LEADERSHIP", "AIRBNB", "AMERICAN BEVERAGE ASSOCIATION", "ANDELL INC", "ARLINGTON PARK", "CITIBANK, NA",
"CVS CAREMARK CORP", "DELAWARE NORTH COMPANIES", "DELL", "DOMINION VOTING SYSTEMS INC", "FAMILY GUIDANCE CENTERS INC",
"HILTON WORLDWIDE", "HUDSON GROUP", "JCDECAUX GROUP", "LYFT", "NORESCO LLC", "PRESENCE HEALTH", "SSP AMERICA INC",
"UBER","UNITED PARCEL SERVICE")
values <- c("Academy for Urban School Leadership", "Airbnb", "American Beverage Assc.", "Andell", "Arlington Park", "Citi",
"CVS", "Delaware North", "Dell", "Dominion Voting", "Family Guidance Ctrs",
"Hilton", "Hudson Grp", "JCDecaux Grp", "Lyft", "Noresco", "Presence Health", "SSP America",
"Uber", "UPS")
nick_name <- setNames(as.list(values), keys)
top <- compensation %>%
filter(TOP20 == 'Yes') %>%
group_by(CLIENT_NAME, CLIENT_INDUSTRY) %>%
summarise(sum=sum(COMPENSATION_AMOUNT), n = n()) %>%
mutate(sum = sum/1000000,
INDUSTRY = if_else(CLIENT_INDUSTRY %in% c('HOSPITALITY / RESTAURANT', 'PUBLIC UTILITIES',
'RETAIL', 'EDUCATION', 'RACING & WAGERING', 'TRANSPORTATION'),
'OTHER INDUSTRY', CLIENT_INDUSTRY),
NICK_NAME = nick_name[CLIENT_NAME])
t <-compensation %>%
filter(TOP20 == 'No') %>%
group_by(CLIENT_NAME) %>%
summarise(sum=sum(COMPENSATION_AMOUNT), n = n()) %>%
mutate(sum = sum/1000000) %>%
ggplot() +
geom_point(aes(n, sum), color = light_colors["gray"], size = 2, alpha = 0.4) +
annotate("text", x = 300, y = .7, label = "99% of cleints paid under\n $2.0M to lobbyists\n in the time period", size = 3)
t + geom_point(data = top, aes(n, sum, color = INDUSTRY), size = 2, alpha = 0.7) +
geom_text_repel(data = top, aes(n, sum, label = NICK_NAME), check_overlap = TRUE, size = 3, hjust = 0, nudge_x = 0.1) +
scale_y_continuous(label=dollar_format()) +
scale_color_manual(values = as.vector(dark_colors[1:6])) +
xlim(0, 650) +
labs(title="Tech Companies, Healthcare Providers, and Industry Associations\n are Among the Highest Paying Clients",
subtitle="Compensation Payments to Lobbyists, 2012 - 2018",
caption="Source: City of Chicago Lobbyist Data, Compensation",
x = "Number of Payments",
y = "Total Compensation (in Millions)") +
theme_claire +
theme(legend.text=element_text(size=6),
legend.title=element_text(size=8),
legend.position = c(0.8, 0.2)) +
guides(color=guide_legend(title="Industry of Top 20"))
In contrast to the vast majority of clients, the top 20 clients in terms of compensation to lobbyists each paid over $2.5M between 2012 and 2018. While any organization, including non-profits and other public service entities, may lobby government, the top 20 clients are almost all private companies with a national profile. The top spender, the American Beverage Association, has consistently paid lobbyists to advocate to the Mayor and City Council against legislation like the proposed Soda Tax and a ban on high-caffeine energy drinks proposed in 2013. Technology companies including Uber, Lyft, and Dell also rank high on the list.
top20cloud <- activity %>%
mutate(TOP20 = ifelse(CLIENT_NAME %in% top_20$CLIENT_NAME, "Yes", "No")) %>%
filter(PERIOD_START > as.Date('2014-12-31') & TOP20 == "Yes") %>%
mutate(ACTION_SOUGHT_WORDS = as.vector(str_split(ACTION_SOUGHT, pattern = c(" ", ", ")))) %>%
#group_by(ACTION) %>%
summarise(WORDS = paste(ACTION_SOUGHT, collapse = ", ")) %>%
mutate(WORDS_SEP = as.vector(str_split(WORDS, pattern = "[^a-zA-Z0-9]? ")))
## Warning in stri_split_regex(string, pattern, n = n, simplify = simplify, :
## longer object length is not a multiple of shorter object length
common_words <- c("A", "AND", "AT", "OF", "IN", "THE", "BE", "TO", "THAT", "HAVE",
"IT", "/", "&", "FOR", "N", "E", "W", "S", "L", "WITH", "ON")
# Probably a better way to do this
#admin <- data.frame(table(b$WORDS_SEP[1])) %>%
# mutate(ACTION = 'ADMINISTRATIVE') %>%
# rename(WORD = Var1, COUNT = Freq) %>%
# arrange(desc(COUNT)) %>%
# slice(1:30)
#both <- data.frame(table(b$WORDS_SEP[2])) %>%
# mutate(ACTION = 'BOTH') %>%
# rename(WORD = Var1, COUNT = Freq) %>%
# arrange(desc(COUNT)) %>%
# slice(1:30)
#legis <- data.frame(table(b$WORDS_SEP[3])) %>%
# mutate(ACTION = 'LEGISLATIVE') %>%
# rename(WORD = Var1, COUNT = Freq) %>%
# arrange(desc(COUNT)) %>%
# slice(1:30)
#word_counts <- admin %>%
# rbind(both) %>%
# rbind(legis) %>%
# filter(!(WORD %in% common_words))
word_counts_top20 <- data.frame(table(top20cloud$WORDS_SEP[1])) %>%
rename(WORD = Var1, COUNT = Freq) %>%
filter(!(WORD %in% common_words)) %>%
arrange(desc(COUNT)) %>%
slice(1:50)
word_counts_top20 %>%
ggplot(aes(size = COUNT, label = WORD, color = COUNT)) +
geom_text_wordcloud() +
scale_size(range = c(2, 8), guide = FALSE) +
scale_color_continuous(low = light_colors['blue'], high = dark_colors['blue']) +
scale_y_continuous(breaks = NULL) +
scale_x_continuous(breaks = NULL) +
labs(x = '', y = '') +
#facet_grid(rows = vars(ACTION), switch="both") +
labs(title="Concerns among the top 20 are different",
subtitle="Most Freqently Used Words in Activity Descriptions Among the Top 20 Clients, 2015-2018",
caption="Source: City of Chicago Lobbyist Data, Activity") +
theme_claire +
theme(panel.background = element_blank(),
panel.border = element_rect(color="black",size=1, fill=NA),
strip.background = element_rect(color="black",size=0.5),
legend.position = "none")
# try log scale? add annotation,
compensation %>%
filter(TOP20 == 'Yes') %>%
group_by(LOBBYIST_NAME) %>%
summarise(sum = sum(COMPENSATION_AMOUNT), log_sum = log10(sum(COMPENSATION_AMOUNT)), n = n()) %>%
mutate(sum = sum/1000000,
cat = if_else(sum < 1, 'No', 'Yes')) %>%
ggplot(aes(reorder(tools::toTitleCase(tolower(LOBBYIST_NAME)), log_sum), log_sum)) +
geom_point(aes(color = cat), stat = 'identity', size = 3) +
scale_color_manual(values = as.vector(dark_colors[c("blue", "red")])) +
labs(title="The Top 20 Clients Paid 63 Lobbyists Over the Time Period;\n 8 Earned Over $1M Each",
subtitle="Log of Total Compensation to Lobbyists by Top 20 Clients, 2012 - 2018",
caption="Source: City of Chicago Lobbyist Data, Compensation",
x = "Lobbyist",
y = "Log Scale of Total Compensation") +
theme_claire +
theme(axis.text.x = element_text(angle = 90, hjust = 1),
legend.position = c(0.15, 0.75)) +
guides(color=guide_legend(title="Paid Over $1M"))
Between 2012 and 2018, the top 20 clients paid 63 lobbyists to represent their interest, with 8 earning over $1M. David Dring, Courtney Nottage, and Michael Kasper, all employed by the lawfirm Fletcher, O’Brien, Kasper, and Nottage, earned over $15M each. John Kelly, Jr., the president of AllCirco earned $13.7M. Victor Reyes and Amy Kurson are partners at the lawfirm Reyes Kurson and each earned about $1M. Patrick Carey and John Dunn are both partners at the lawfirm McGuire Woods and earned $3.0M and $4.8M, respectively.
# Set threshold for industries to show individually
keep <- compensation %>%
filter(PERIOD_START > as.Date('2014-12-31')) %>%
group_by(CLIENT_INDUSTRY) %>%
summarise(sum = sum(COMPENSATION_AMOUNT)) %>%
arrange(desc(sum)) %>%
mutate(KEEP = if_else(sum > 7000000, 1, 0))
# Set Lawfirm and Industry Lookups for labeling
lobbyist_name <- c("VICTOR REYES", "AMY KURSON", "PATRICK CAREY", "JOHN DUNN", "JOHN KELLY, JR.",
"DAVID DRING", "COURTNEY NOTTAGE", "MICHAEL KASPER")
lawfirm <- c("", "RK", "MW", "MW", "ALLCIRCO",
"FOKN", "FOKN", "FOKN")
law_names <- setNames(as.list(lawfirm), lobbyist_name)
full_industry <- c("REAL ESTATE & CONSTRUCTION", "INFO/TECH PRODUCTS OR SERVICES", "HOSPITALITY / RESTAURANT",
"TRADE & PROFESSIONAL ASSOCIATIONS", "FINANCIAL / BANKING")
short_industry <- c("REAL ESTATE", "TECH", "HOSPITALITY",
"TRADE & PRO ASSCS", "FINANCIAL")
industry_lookup <- setNames(as.list(short_industry), full_industry)
compensation %>%
left_join(keep, by = "CLIENT_INDUSTRY") %>%
mutate(LAWFIRM = if_else(LOBBYIST_NAME %in% names(law_names), as.character(law_names[LOBBYIST_NAME]), "OTHER"),
REAL_ESTATE = if_else(str_detect(CLIENT_INDUSTRY, "REAL ESTATE"), "Yes", "No"),
REAL_ESTATE = if_else(is.na(REAL_ESTATE), "No", REAL_ESTATE),
CLIENT_INDUSTRY = if_else(KEEP == 0, "OTHER", CLIENT_INDUSTRY),
CLIENT_INDUSTRY = if_else(CLIENT_INDUSTRY %in% names(industry_lookup), as.character(industry_lookup[CLIENT_INDUSTRY]), CLIENT_INDUSTRY)) %>%
filter(PERIOD_START > as.Date('2014-12-31') & KEEP == 1) %>%
group_by(CLIENT_INDUSTRY, TOP20, LAWFIRM) %>%
summarise(sum = sum(COMPENSATION_AMOUNT)) %>%
mutate(sum = sum/1000000) %>%
ggplot(aes(y = sum, axis1 = CLIENT_INDUSTRY, axis2 = LAWFIRM)) +
geom_alluvium(aes(fill = TOP20)) +
geom_stratum(width = 1/12, fill = "black", color = "grey") +
geom_label(stat = "stratum", label.strata = TRUE) +
scale_x_discrete(limits = c("Top 20 Clients", "Lawfirms"), expand = c(.05, .05)) +
scale_y_continuous(label=dollar_format()) +
scale_fill_manual(values = as.vector(dark_colors[4:3])) +
labs(title="Top 20 clients provide the majority of the lobbying revenue for the major lawfirms",
subtitle="Compensation Flow Between Industries and Lawfirms, 2015-2018",
caption="Source: City of Chicago Lobbyist Data, Compensation",
y = "Total Compensation (in Millions)") +
theme_claire +
theme(legend.position = c(.95, .85))
The top 20 clients are both a large share of the compensation coming from their respective industries, and a significant proportion of the revenue at the major law firms. Also note that while real estate-related lobbying activities are the most commmon, no real estate developer is among the top 20 clients, nor do they employ any of the major lobbying firms.
#council_last <- str_trim(toupper(str_extract(council$` Person Name`, '^[A-Za-z\']+')))
council %<>%
mutate(LAST_NAME = str_trim(toupper(str_extract(council$` Person Name`, '^[A-Za-z\']+'))),
LAST_NAME = if_else(str_detect(` Person Name`, 'Moore, D'), 'DAVID MOORE', LAST_NAME),
LAST_NAME = if_else(str_detect(` Person Name`, 'Moore, J'), 'JOE MOORE', LAST_NAME))
alderman_contributions <- contribution %>%
mutate(ALDERMAN = "") %>%
mutate(ALDERMAN = if_else(str_detect(RECIPIENT, 'ARENA'), 'ARENA', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'AUSTIN'), 'AUSTIN', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'BEALE'), 'BEALE', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'BROOKINS'), 'BROOKINS', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'BURKE'), 'BURKE', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'BURNETT'), 'BURNETT', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'CAPPLEMAN'), 'CAPPLEMAN', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'CARDENAS'), 'CARDENAS', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'COCHRAN'), 'COCHRAN', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'CURTIS'), 'CURTIS', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'DOWELL'), 'DOWELL', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'EMANUEL'), 'EMANUEL', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'ERVIN'), 'ERVIN', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'FOULKES'), 'FOULKES', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'HAIRSTON'), 'HAIRSTON', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'HARRIS'), 'HARRIS', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'HOPKINS'), 'HOPKINS', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'KING'), 'KING', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'LAURINO'), 'LAURINO', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'LOPEZ'), 'LOPEZ', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'MALDONADO'), 'MALDONADO', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'MELL'), 'MELL', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'MITCHELL'), 'MITCHELL', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'MITTS'), 'MITTS', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'JOE MOORE'), 'JOE MOORE', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'DAVID MOORE'), 'DAVID MOORE', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'MORENO'), 'MORENO', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'MUNOZ'), 'MUNOZ', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'NAPOLITANO'), 'NAPOLITANO', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, "O'CONNOR"), "O'CONNOR", ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, "O'SHEA"), "O'SHEA", ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'OSTERMAN'), 'OSTERMAN', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'PAWAR'), 'PAWAR', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'QUINN'), 'QUINN', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'RAMIREZ'), 'RAMIREZ', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'REBOYRAS'), 'REBOYRAS', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'REILLY'), 'REILLY', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'SADLOWSKI'), 'SADLOWSKI', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'SANTIAGO'), 'SANTIAGO', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'SAWYER'), 'SAWYER', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'SCOTT'), 'SCOTT', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'SILVERSTEIN'), 'SILVERSTEIN', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'SMITH'), 'SMITH', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'SOLIS'), 'SOLIS', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'SPOSATO'), 'SPOSATO', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'TABARES'), 'TABARES', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'TALIAFERRO'), 'TALIAFERRO', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'THOMPSON'), 'THOMPSON', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'TUNNEY'), 'TUNNEY', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'VALENCIA'), 'VALENCIA', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'VILLEGAS'), 'VILLEGAS', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'WAGUESPACK'), 'WAGUESPACK', ALDERMAN),
ALDERMAN = if_else(str_detect(RECIPIENT, 'ZALEWSKI'), 'ZALEWSKI', ALDERMAN)
) %>%
filter(ALDERMAN != "" & ALDERMAN != "EMANUEL" & ALDERMAN != "VALENCIA")
ald_totals <- alderman_contributions %>%
filter(CONTRIBUTION_DATE > as.Date('2014-12-31')) %>%
group_by(ALDERMAN) %>%
summarise(sum = sum(AMOUNT), n = n()) %>%
arrange(desc(sum))
# Set names for annotations
high_name <- 'BURKE'
high_mid_name <- 'LOPEZ'
mid_name <- 'CAPPLEMAN'
low_mid_name <- 'SADLOWSKI'
low_name <- 'TABARES'
# Set amounts for annotations
high_amt <- '$84k'
high_mid_amt <- '$20k'
mid_amt <- '$14k'
low_mid_amt <- '$5k'
low_amt <- '$0k'
alderman_contributions %>%
filter(CONTRIBUTION_DATE > as.Date('2014-12-31')) %>%
left_join(ald_totals, by = 'ALDERMAN') %>% #glimpse()
#mutate(ALDERMAN = tools::toTitleCase(tolower(ALDERMAN))) %>% glimpse()
ggplot() +
geom_boxplot(aes(reorder(ALDERMAN, sum), AMOUNT), alpha = 0.8) +
coord_flip() +
annotate("text", x = 49.7, y = 1600, label = "Total", size = 3) +
annotate("text", x = high_name, y = 1600, label = high_amt, size = 3) +
annotate("text", x = high_mid_name, y = 1600, label = high_mid_amt, size = 3) +
annotate("text", x = mid_name, y = 1600, label = mid_amt, size = 3) +
annotate("text", x = low_mid_name, y = 1600, label = low_mid_amt, size = 3) +
annotate("text", x = low_name, y = 1600, label = low_amt, size = 3) +
annotate("text", x = 'TABARES', y = 600, label = "Appointed on July 13, 2018 to replace Ald. Zalewski in 23rd Ward", size = 2) +
annotate("text", x = 'ZALEWSKI', y = 700, label = "Resigned from 23rd Ward\n on May 31, 2018", size = 2) +
annotate("rect", xmin = high_mid_name, xmax = 50, ymin = 0, ymax = 1550, fill = light_colors["orange"], alpha = .2) +
annotate("rect", xmin = mid_name, xmax = high_mid_name, ymin = 0, ymax = 1550, fill = light_colors["green"], alpha = .2) +
annotate("rect", xmin = low_mid_name, xmax = mid_name, ymin = 0, ymax = 1550, fill = light_colors["purple"], alpha = .2) +
annotate("rect", xmin = 0, xmax = low_mid_name, ymin = 0, ymax = 1550, fill = light_colors["blue"], alpha = .2) +
annotate("text", x = 49.5, y = 200, label = "Charged with attempted extortion on Jan 3, 2019", size = 2, fontface = 2) +
scale_y_continuous(label=dollar_format()) +
labs(title="Since the 2015 Municipal Election, Lobbyists Have Contributed\n Significant Amounts to Aldermen",
subtitle="Distribution of Lobbyist Contributions to Aldermen Ordered by Total, 2015 - 2018",
caption="Source: City of Chicago Lobbyist Data, Contributions",
x = "Alderman (ordered by total lobbyist contributions)",
y = "Contribution Amount") +
theme_claire
Virtually all elected members of the City Council received contributions from lobbyists since the last municipal election; the only exception is Ald. Tabares who was appointed to on July 13, 2018. There is huge variation in the total contributions from lobbyists since the last municipal election. For example, Ald. Reilly of the 42nd Ward (incl. River North, Gold Cost, and Streeterville), first elected in 2007 and Vice Mayor since 2015, received over $600k while Ald. Mitchell, a first term alderman from the 7th Ward (incl. South Shore, South Chicago, and Calumet Heights) received under $1k. Ald. Ed Burke was the Finance Committee Chairman and received the highest total contributions before being indicted for attempted extortion on January 3, 2019. Note that campaign contributions by registered lobbyists are limited to $1,500 per candidate per calendar year by the Chicago Govermental Ethics Ordinance.
contrib_levels <- c(NA, '$0 - $4,999', '$5,000 - $9,999', '$10,000 - $19,999', '$20,000 - $39,999', '$40,000')
addNA(contrib_levels)
## [1] <NA> $0 - $4,999 $5,000 - $9,999 $10,000 - $19,999
## [5] $20,000 - $39,999 $40,000
## 6 Levels: $0 - $4,999 $10,000 - $19,999 $20,000 - $39,999 ... <NA>
wards %>%
left_join(council %>% select(`Ward/Office`, LAST_NAME), by = c("ward" = "Ward/Office")) %>% #glimpse() %>%
left_join(ald_totals, by = c("LAST_NAME" = "ALDERMAN")) %>%
#filter(is.na(sum)) %>%
mutate(Total = if_else(sum < 5000, '$0 - $4,999',
if_else(sum >= 5000 & sum < 10000, '$5,000 - $9,999',
if_else(sum >= 10000 & sum < 20000, '$10,000 - $19,999',
if_else(sum >= 20000 & sum < 40000, '$20,000 - $39,999',
if_else(sum >= 40000, '$40,000', 'OTHER'))))),
Total = factor(Total, levels = contrib_levels),
lon = map_dbl(geometry, ~st_centroid(.x)[[1]]),
lat = map_dbl(geometry, ~st_centroid(.x)[[2]])
) %>%
ggplot() +
geom_sf(aes(fill = Total)) +
geom_text(aes(x = lon, y = lat, label = ward), size = 3) +
labs(title="",
subtitle="Map of Total Contributions to Alderman by Ward, 2015-2018",
caption="Source: City of Chicago Lobbyist Data, Contributions",
x = "",
y = "") +
scale_fill_manual(values = c('#eff3ff', '#bdd7e7', '#6baed6', '#3182bd', '#08519c'), na.value = light_colors[['gray']]) +
theme_claire +
theme(panel.grid.major.x = element_blank(),
panel.grid.major.y = element_blank())
[TEXT HERE]
# shows more about who is and who isn't
# Bin lobbyists by location? octant of community areas
# sankey diagram
paid_by_top20 <- compensation %>%
filter(TOP20 == 'Yes') %>%
group_by(LOBBYIST_NAME) %>%
summarise(sum = sum(COMPENSATION_AMOUNT), n = n()) %>%
filter(sum >= 1000000)
alderman_contributions %>%
mutate(paid_top20 = if_else(LOBBYIST_NAME %in% paid_by_top20$LOBBYIST_NAME | LOBBYIST_NAME == 'REYES KURSON', TRUE, FALSE))%>%
filter(CONTRIBUTION_DATE > as.Date('2014-12-31') & paid_top20) %>%
left_join(ald_totals, by = 'ALDERMAN') %>%
group_by(ALDERMAN, LOBBYIST_NAME) %>%
summarise(sum = sum(AMOUNT), n = n()) %>%
ggplot() +
geom_tile(aes(reorder(LOBBYIST_NAME, sum), reorder(ALDERMAN, sum), fill = sum), color = 'black') +
scale_fill_gradient(low = light_colors['blue'], high = dark_colors['blue'], label=dollar_format()) +
labs(title="The Highest Paid Lobbyists by the Top 20 Clients Make\n Contributions to Almost Every Alderman",
subtitle="Total Contributions by Top Paid Lobbyists, 2015-2018",
caption="Source: City of Chicago Lobbyist Data, Contributions",
x = "Lobbyist",
y = "Alderman (ordered by total contributions from included lobbyists)") +
theme_claire +
theme(axis.text.x = element_text(angle = 90, hjust = 1),
panel.grid = element_blank()) +
guides(fill=guide_legend(title="Total Payments"))
The lobbyists paid the most compensation by the top 20 firms appear to have a strategy of blanket, moderate, financial support for almost all aldermen. One notable exception is John Kelly, President and Owner of the public affairs consulting firm All-Circo, Inc, who appears to concentrate on only a few. Two of the eight attorneys paid over $1M, Amy Kurson and Victor Reyes, are both partners at the lawfirm Reyes Kurson. Their contribution data was not included in the data protal contribution records, so aggregate records from the firm were added from IllinoisSunshine.com.